﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using GRWL.BZSC.UI.CustomCtrl;
using GRWL.BZSC.UI.BaseDataSvc;
using UserCtrl;

namespace GRWL.BZSC.UI
{
    public partial class OrderFrm : BaseFrm
    {
        private GRWL.BZSC.Common.EnumCommon.OrderTypes _OrderType;
        public GRWL.BZSC.Common.EnumCommon.OrderTypes OrderType
        {
            get
            {
                return _OrderType;
            }
            set
            {
                _OrderType = value;
                if (value == GRWL.BZSC.Common.EnumCommon.OrderTypes.CG)
                {
                    Text = "采购单";
                }
                else
                {
                    Text = "订货单";
                }
                BillPrefix = value.ToString(); 
            }
        }

        bool bEdit, bConfirm, bPrint;

        private TB_Order tbOrder;
        private TB_OrderDetail[] tbOrderDetails;
        private XOrder xMain;
        private XOrderDetail[] xDetials;

        private TB_Trader Trader;
        private TB_Department Department;
        //private TB_Department[] Departments;

        //private TB_User[] Users;
        private XUser[] XUsers;

        //private DataTable tXUsers;
        private ArrayList FieldsRef = new ArrayList();

        /// <summary>
        /// 临时变量日期控件
        /// </summary>
        DateTimePicker _DTP = new DateTimePicker();
        UDataGridView theView;

        #region 窗体部分
        public OrderFrm()
        {
            InitializeComponent();

            this.BaseDataProxy = new BaseDataClient();
            this.BaseDataProxy.Open();

            this.codeRule = new CodeRuleFrm.CodeRule();

            EditStatus = Common.BillOperateType.None;

            OrderType = GRWL.BZSC.Common.EnumCommon.OrderTypes.CG;
        }

        private void OrderFrm_Load(object sender, EventArgs e)
        {
            theView = gvOrder;
            theView.Controls.Add(this._DTP);  //把时间控件加入DataGridView
            this._DTP.Visible = false;  //先不让它显示
            this._DTP.Format = DateTimePickerFormat.Custom;
            this._DTP.TextChanged += new EventHandler(dtp_TextChange); //为时间控件加入事件dtp_TextChange            

            theView.CellClick += new DataGridViewCellEventHandler(theView_CellClick);
            theView.ColumnWidthChanged += new DataGridViewColumnEventHandler(theView_ColumnWidthChanged);
            theView.Scroll += new ScrollEventHandler(theView_Scroll);

            theView.CellDoubleClick += new DataGridViewCellEventHandler(theView_CellDoubleClick);
            theView.CellEndEdit += new DataGridViewCellEventHandler(theView_CellEndEdit);
            theView.RowsAdded += new DataGridViewRowsAddedEventHandler(theView_RowsAdded);
            theView.RowsRemoved += new DataGridViewRowsRemovedEventHandler(theView_RowsRemoved);
            theView.CellFormatting += new DataGridViewCellFormattingEventHandler(theView_CellFormatting);

            theView.AutoGenerateColumns = false;
            theView.DataSource = tDetail;

            DisabledControls();

            if (OrderType == GRWL.BZSC.Common.EnumCommon.OrderTypes.CG)
            {
                //允许看见导入到采购单的单号
                theView.Columns["prevCode"].Visible = true;
            }
            if (OrderType == GRWL.BZSC.Common.EnumCommon.OrderTypes.DH)
            {
                // 订货单中从上一流程导入单据暂时不支持
                btnSelect.Visible = false;
                // 是否生产
                lIsProduce.Visible = true;
                chkIsProduce.Visible = true;

                theView.Columns["traderFlag"].Visible = true;
                theView.Columns["traderMtrlCode"].Visible = true;
                theView.Columns["BoxCode"].Visible = true;
                theView.Columns["SubBoxCode"].Visible = true;
            }

            Name = BillPrefix;
        }

        #endregion

        #region GridView部分
        void theView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            Common.CellFormatColor(sender, e, EditStatus);
        }

        void theView_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
        {
            Common.ShowDataGridViewRowNo((UDataGridView)sender);
        }

        void theView_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
        {
            Common.ShowDataGridViewRowNo((UDataGridView)sender);
        }

        private void theView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex < 0)
                return;

            if ((EditStatus != Common.BillOperateType.Add) & (EditStatus != Common.BillOperateType.Update))
            {
                return;
            }

            //物资编号
            if ((theView.Columns[e.ColumnIndex].Name == "MaterialCode") | (theView.Columns[e.ColumnIndex].Name == "MaterialName"))
            {
                FindMaterialFrm frm = new FindMaterialFrm();
                frm.StockNullable = true;
                frm.Text = "选择物资";
                if (frm.ShowDialog() == DialogResult.OK)
                {
                    theView.CurrentRow.Cells["MaterialId"].Value = frm.SelectorItem.Id;
                    theView.CurrentRow.Cells["MaterialCode"].Value = frm.SelectorItem.Code;
                    theView.CurrentRow.Cells["MaterialName"].Value = frm.SelectorItem.CnName;
                    theView.CurrentRow.Cells["Specs"].Value = frm.SelectorItem.Specs;
                    theView.CurrentRow.Cells["Unit"].Value = frm.SelectorItem.Unit;
                    // 非标准规格字段
                    theView.CurrentRow.Cells["specs"].Value = frm.SelectorItem.Specs;
                }
            }
        }

        void theView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            if ((EditStatus != Common.BillOperateType.Add) & (EditStatus != Common.BillOperateType.Update))
            {
                return;
            }

            //物资编号编辑后,搜索新物资资料更新有关字段
            if (theView.Columns[e.ColumnIndex].Name == "MaterialCode")
            {
                string sMaterialCode = (string)theView.CurrentRow.Cells["MaterialCode"].Value;
                QMaterial[] QMaterialFind = BaseDataProxy.FindMaterials(false, null, null, null, sMaterialCode, null,null,null,null,null);
                if ((QMaterialFind == null) || (QMaterialFind.Count() == 0))
                    return;
                if (theView.CurrentRow.Cells["MaterialId"].Value.ToString() == QMaterialFind[0].Id.ToString())
                    return;
                theView.CurrentRow.Cells["MaterialId"].Value = QMaterialFind[0].Id;
                theView.CurrentRow.Cells["MaterialCode"].Value = QMaterialFind[0].Code;
                theView.CurrentRow.Cells["MaterialName"].Value = QMaterialFind[0].CnName;
                theView.CurrentRow.Cells["Specs"].Value = QMaterialFind[0].Specs;
                theView.CurrentRow.Cells["Unit"].Value = QMaterialFind[0].Unit;
                // 非标准规格字段
                theView.CurrentRow.Cells["specs"].Value = QMaterialFind[0].Specs;
                return;
            }

            //数量、单价等字段编辑后,刷新有关金额计算
            if ((theView.Columns[e.ColumnIndex].Name == "Num") || (theView.Columns[e.ColumnIndex].Name == "Price") ||
            (theView.Columns[e.ColumnIndex].Name == "Discount") || (theView.Columns[e.ColumnIndex].Name == "TaxRate") ||
            (theView.Columns[e.ColumnIndex].Name == "TaxPrice"))
            {
                ReCalcRowMoney(theView.CurrentRow);
            }
        }

        private void theView_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            UDataGridView theView = (UDataGridView)sender;
            // 判断所在是否日期选择的列
            if (theView.Columns[e.ColumnIndex].ValueType == typeof(DateTime))
            {
                Rectangle _Rectangle = theView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true); //得到所在单元格位置和大小
                this._DTP.Size = new Size(_Rectangle.Width, _Rectangle.Height); //把单元格大小赋给时间控件
                this._DTP.Location = new Point(_Rectangle.X, _Rectangle.Y); //把单元格位置赋给时间控件
                if (theView.CurrentCell.Style.BackColor != Color.Empty)
                    _DTP.CalendarForeColor = theView.CurrentCell.Style.BackColor;
                if ((!theView.CurrentCell.ReadOnly) && (!string.IsNullOrEmpty(theView.CurrentCell.Value.ToString())))
                    this._DTP.Value = (DateTime)theView.CurrentCell.Value;
                this._DTP.Visible = true;  //可以显示控件了
            }
            else
            {
                this._DTP.Visible = false;
            }
        }

        private void theView_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
        {
            this._DTP.Visible = false;
        }

        private void theView_Scroll(object sender, ScrollEventArgs e)
        {
            this._DTP.Visible = false;
        }

        private void dtp_TextChange(object sender, EventArgs e)
        {
            theView.CurrentCell.Value = this._DTP.Text.ToString();  //时间控件选择时间时，就把时间赋给所在的单元格
        }

        #endregion

        #region 自定义过程/函数
        /// <summary>
        /// 刷新指定行中的金额计算
        /// </summary>
        /// <param name="rCalc"></param>
        /// <returns></returns> 
        private bool ReCalcRowMoney(DataGridViewRow rCalc)
        {
            if ((EditStatus != Common.BillOperateType.Add) & (EditStatus != Common.BillOperateType.Update))
                return false;

            rCalc.Cells["TaxPrice"].Value = DBNull.Value;
            rCalc.Cells["TaxAmount"].Value = DBNull.Value;
            rCalc.Cells["DeductAmount"].Value = DBNull.Value;
            rCalc.Cells["Amount"].Value = DBNull.Value;

            decimal dNum, dPrice, dDiscount, dTaxRate, dTaxPrice;

            if (theView.CurrentRow.Cells["Num"].Value == null)
                return false;
            dNum = Common.StringToDecimal(rCalc.Cells["Num"].Value.ToString());

            if (theView.CurrentRow.Cells["Price"].Value == null)
                return false;
            dPrice = Common.StringToDecimal(rCalc.Cells["Price"].Value.ToString());

            if (rCalc.Cells["Discount"].Value == null)
                return false;
            dDiscount = Common.StringToDecimal(rCalc.Cells["Discount"].Value.ToString());

            rCalc.Cells["DeductAmount"].Value = dNum * dPrice * (1 - dDiscount);
            rCalc.Cells["Amount"].Value = dNum * dPrice * dDiscount;

            if (theView.CurrentRow.Cells["TaxRate"].Value == null)
                //return false;
                dTaxRate = 0;
            else
                dTaxRate = Common.StringToDecimal(rCalc.Cells["TaxRate"].Value.ToString());

            dTaxPrice = dPrice * (1 + dTaxRate);
            rCalc.Cells["TaxPrice"].Value = dTaxPrice;
            rCalc.Cells["TaxAmount"].Value = dNum * dTaxPrice * dDiscount;

            return true;
        }

        /// <summary>
        /// 刷新所有行中的金额计算
        /// </summary>
        /// <returns></returns> 
        private bool ReCalcAllMoney()
        {
            foreach (DataGridViewRow dgvr in theView.Rows)
            {
                if (!ReCalcRowMoney(dgvr))
                    return false;
            }
            return true;
        }

        /// <summary>
        /// 建立 DataTable 与 GridView 中字段的对应关系,在以后的数据互相转换(DataTable - GridView)中使用此处建立的关系
        /// </summary>
        /// <returns></returns> 
        private bool CreateFieldRef()
        {
            FieldsRef.Clear();
            foreach (DataColumn dc in tDetail.Columns)
            {
                string cName = dc.ColumnName;
                bool bFind = false;
                foreach (DataGridViewColumn dgvc in theView.Columns)
                {
                    if (dgvc.DataPropertyName.ToLower() == cName.ToLower())
                    {
                        FieldsRef.Add(dgvc.Name);
                        bFind = true;
                        break;
                    }
                }
                if (!bFind)
                    FieldsRef.Add("");
            }
            return true;
        }

        /// <summary>
        /// 重写继承窗体中编辑状态转换后的处理代码
        /// </summary> 
        public override void EditStatusChanged()
        {
            RefreshStatus();
            //btnAppend.Enabled = (EditStatus != Common.BillOperateType.Add) && (EditStatus != Common.BillOperateType.Update);
            //btnOpen.Enabled = (EditStatus == Common.BillOperateType.None);
            btnSave.Enabled = bEdit;
            btnSelect.Enabled = bEdit;
            btnDelete.Enabled = bEdit;
            btnAddItem.Enabled = bEdit;
            btnDelItem.Enabled = bEdit;
            btnMaterial.Enabled = bEdit;
            btnConfirm.Enabled = bConfirm;
            btnPrint.Enabled = bPrint;
        }

        private void RefreshStatus()
        {
            bEdit = (EditStatus == Common.BillOperateType.Add) || (EditStatus == Common.BillOperateType.Update);
            bConfirm = (tMain.Rows.Count > 0);
            if (bConfirm)
                bConfirm = (Common.StringToInt(tMain.Rows[0]["id"].ToString()) > 0);
            bPrint = (EditStatus != Common.BillOperateType.Add) && (EditStatus != Common.BillOperateType.Update);
        }

        /// <summary>
        /// 编辑控件的输入状态控制
        /// </summary> 
        private void DisabledControls()
        {
            SetControlsStatus(false);
        }

        /// <summary>
        /// 编辑控件的输入状态控制
        /// </summary>
        private void EnabledControls()
        {
            SetControlsStatus(true);
        }

        private void SetControlsStatus(bool SetEnabledFlag)
        {
            //edtBillCode.Enabled = SetEnabledFlag;
            edtOrderDate.Enabled = SetEnabledFlag;
            edtDeliveryDate.Enabled = SetEnabledFlag;
            edtBillStatus.Enabled = SetEnabledFlag;

            edtTrader.Enabled = SetEnabledFlag;
            edtAddress.Enabled = SetEnabledFlag;
            chkIsProduce.Enabled = SetEnabledFlag;

            edtDepartment.Enabled = SetEnabledFlag;
            edtBizMan.Enabled = SetEnabledFlag;
            chkIsCheck.Enabled = SetEnabledFlag;
            cmbTaxRate.Enabled = SetEnabledFlag;

            edtMemo.Enabled = SetEnabledFlag;
            //edtCreateTime.Enabled = SetEnabledFlag;
            edtOperator.Enabled = SetEnabledFlag;

            //assessorUTextBox.Enabled = SetEnagledFlag;
            //menderUTextBox.Enabled = SetEnagledFlag;
            //updateTimeUDateTimePicker.Enabled = SetEnagledFlag;
            //verifyTimeUDateTimePicker.Enabled = SetEnagledFlag;

            theView.ReadOnly = !SetEnabledFlag;

            //指定表格中只读的字段，防止被用户错误修改
            if (SetEnabledFlag)
            {
                theView.Columns["MaterialName"].ReadOnly = SetEnabledFlag;
                theView.Columns["Unit"].ReadOnly = SetEnabledFlag;
                theView.Columns["taxPrice"].ReadOnly = SetEnabledFlag;
                theView.Columns["deductAmount"].ReadOnly = SetEnabledFlag;
                theView.Columns["taxAmount"].ReadOnly = SetEnabledFlag;
                theView.Columns["reqNum"].ReadOnly = SetEnabledFlag;
                theView.Columns["finishedNum"].ReadOnly = SetEnabledFlag;
                theView.Columns["PrevCode"].ReadOnly = SetEnabledFlag;
            }
        }

        /// <summary>
        /// 绑定数据到编辑控件
        /// </summary>
        private void SetControlsData()
        {
            string strDayTime;

            edtBillCode.Text = tMain.Rows[0]["code"].ToString();
            edtBillStatus.Text = tMain.Rows[0]["status"].ToString();

            edtAddress.Text = tMain.Rows[0]["address"].ToString();
            edtBizMan.Text = tMain.Rows[0]["BusinessmanName"].ToString();
            edtMemo.Text = tMain.Rows[0]["memo"].ToString();

            edtOperator.Text = tMain.Rows[0]["OperatorName"].ToString();
            edtMender.Text = tMain.Rows[0]["MenderName"].ToString();
            edtAssessor.Text = tMain.Rows[0]["AssessorName"].ToString();

            strDayTime = tMain.Rows[0]["orderDate"].ToString();
            if (!String.IsNullOrEmpty(strDayTime))
                edtOrderDate.Value = Convert.ToDateTime(strDayTime);

            strDayTime = tMain.Rows[0]["deliveryDate"].ToString();
            if (!String.IsNullOrEmpty(strDayTime))
                edtDeliveryDate.Value = Convert.ToDateTime(strDayTime);

            strDayTime = tMain.Rows[0]["createTime"].ToString();
            if (!String.IsNullOrEmpty(strDayTime))
                edtCreateTime.Value = Convert.ToDateTime(strDayTime);

            strDayTime = tMain.Rows[0]["updateTime"].ToString();
            if (!String.IsNullOrEmpty(strDayTime))
                edtUpdateTime.Text = strDayTime;

            strDayTime = tMain.Rows[0]["verifyTime"].ToString();
            if (!String.IsNullOrEmpty(strDayTime))
                edtVerifyTime.Text = strDayTime;

            if (!string.IsNullOrEmpty(tMain.Rows[0]["trader"].ToString()))
            {
                SelectItem item = new SelectItem();
                Trader = BaseDataProxy.GetTrader((int)tMain.Rows[0]["trader"]);
                if (Trader != null)
                {
                    item.Name = Trader.name;
                    item.Key = Trader.code;
                    item.Value = Trader.id.ToString();
                    edtTrader.SetSelected(item);
                }
            }

            if (!string.IsNullOrEmpty(tMain.Rows[0]["department"].ToString()))
            {
                SelectItem item = new SelectItem();
                Department = BaseDataProxy.GetDepartment((int)tMain.Rows[0]["department"]);
                if (Department != null)
                {
                    item.Name = Department.name;
                    item.Key = Department.code;
                    item.Value = Department.id.ToString();
                    edtDepartment.SetSelected(item);
                }
            }

            if (!string.IsNullOrEmpty(tMain.Rows[0]["isProduce"].ToString()))
                chkIsProduce.Checked = (bool)tMain.Rows[0]["isProduce"];
            else
                chkIsProduce.Checked = false;
            if (!string.IsNullOrEmpty(tMain.Rows[0]["isCheck"].ToString()))
                chkIsCheck.Checked = (bool)tMain.Rows[0]["isCheck"];
            else
                chkIsCheck.Checked = false;

            UpdateBizManList(Common.StringToInt(tMain.Rows[0]["department"].ToString()));

            // 检查窗体税目中有无该项目，没有就加入
            if (!string.IsNullOrEmpty(tMain.Rows[0]["tax"].ToString()))
            {
                string cTax = tMain.Rows[0]["tax"].ToString();
                if (cmbTaxRate.Items.IndexOf(cTax) < 0)
                    cmbTaxRate.Items.Add(cTax);

                cmbTaxRate.SelectedIndex = cmbTaxRate.Items.IndexOf(cTax);
            }
            else
                cmbTaxRate.SelectedIndex = 0;

            theView.DataSource = tDetail;

            // datatable -> gridview， datatable记录填入到gridview
            //CreateFieldRef();
            //theView.SuspendLayout();
            //theView.Rows.Clear();

            //foreach (DataRow dr in tDetail.Rows)
            //{
            //    int rIndex = theView.Rows.Add();

            //    int iindex = 0;
            //    foreach (string fName in FieldsRef)
            //    {
            //        if (string.IsNullOrEmpty(fName))
            //        {
            //            iindex++;
            //            continue;
            //        }
            //        theView.Rows[rIndex].Cells[fName].Value = dr[iindex].ToString();
            //        iindex++;
            //    }
            //}

            ////theView.AutoResizeColumns();
            //theView.ResumeLayout();

        }

        /// <summary>
        /// 编辑控件绑定数据保存回datatable
        /// </summary>
        /// <returns></returns> 
        private bool GetControlsData()
        {
            //tMain.Rows[0]["code"] = edtBillCode.Text;
            tMain.Rows[0]["orderDate"] = edtOrderDate.Value;
            tMain.Rows[0]["deliveryDate"] = edtDeliveryDate.Value;

            try
            {
                tMain.Rows[0]["trader"] = edtTrader.SelectedValue();
            }
            catch
            {
                MessageBox.Show("保存单据中往来单位不可为空。");
                return false;
            }
            tMain.Rows[0]["isProduce"] = chkIsProduce.Checked;
            tMain.Rows[0]["address"] = edtAddress.Text;

            try
            {
                tMain.Rows[0]["department"] = edtDepartment.SelectedValue();
            }
            catch
            {
                MessageBox.Show("保存单据中部门不可为空。");
                return false;
            }

            if (edtBizMan.SelectedItem == null)
            {
                tMain.Rows[0]["businessman"] = DBNull.Value;
                tMain.Rows[0]["BusinessmanName"] = "";
            }
            else
            {
                tMain.Rows[0]["businessman"] = ((TB_User)edtBizMan.SelectedItem).id;
                tMain.Rows[0]["BusinessmanName"] = ((TB_User)edtBizMan.SelectedItem).name;
            }

            tMain.Rows[0]["isCheck"] = chkIsCheck.Checked;
            if (cmbTaxRate.SelectedIndex == 0)
                tMain.Rows[0]["tax"] = DBNull.Value;
            else
                tMain.Rows[0]["tax"] = Common.StringToDecimal(cmbTaxRate.Text);

            tMain.Rows[0]["memo"] = edtMemo.Text;

            edtOperator.Text = tMain.Rows[0]["OperatorName"].ToString();
            edtMender.Text = tMain.Rows[0]["MenderName"].ToString();

            if (theView.Rows.Count == 0)
            {
                MessageBox.Show("单据明细记录为空不可以保存。");
                return false;
            }

            foreach (DataGridViewRow TheRow in theView.Rows)
            {
                if ((string.IsNullOrEmpty(TheRow.Cells["MaterialId"].Value.ToString())) || (string.IsNullOrEmpty(TheRow.Cells["MaterialCode"].Value.ToString())))
                {
                    theView.CurrentCell = TheRow.Cells["MaterialCode"];
                    MessageBox.Show("输入的物资不正确，请重新输入。");
                    return false;
                }
            }

            // gridview -> datatable
            //CreateFieldRef();
            //tDetail.Clear();

            //for (int i = 0; i < this.theView.Rows.Count; i++)
            //{
            //    DataRow NewDetailRow = tDetail.NewRow();
            //    int iindex = 0;
            //    foreach (string fName in FieldsRef)
            //    {
            //        if (string.IsNullOrEmpty(fName))
            //        {
            //            iindex++;
            //            continue;
            //        }

            //        try
            //        {
            //            NewDetailRow[iindex] = theView.Rows[i].Cells[fName].Value;
            //        }
            //        catch
            //        {
            //            // 忽略转换错误，默认值为空
            //        }
            //        finally
            //        {
            //            iindex++;
            //        }
            //    }
            //    tDetail.Rows.Add(NewDetailRow);
            //}
            return true;
        }
        #endregion

        #region 按钮部分
        private void btnAppend_Click(object sender, EventArgs e)
        {
            //放弃新单
            //if (EditStatus == Common.BillOperateType.Add)
            //{
            //    EditStatus = Common.BillOperateType.None;
            //    SetControlsStatus(false);
            //    return;
            //}

            //新单输入
            EditStatus = Common.BillOperateType.Add;
            SetControlsStatus(true);

            tMain.Clear();
            DataRow NewMainRow = tMain.NewRow();

            // 开新单时，单号为空，保存时申请后显示
            NewMainRow["code"] = ""; // BaseDataProxy.GetSerialNo(1, BillPrefix, 4, true, true, true);
            NewMainRow["operator"] = SysLoginUserInfo.UserId;
            //NewMainRow["OperatorCode"] = SysLoginUserInfo.UserCode;
            NewMainRow["OperatorName"] = SysLoginUserInfo.UserName;
            NewMainRow["createTime"] = DateTime.Now;
            NewMainRow["orderType"] = BillPrefix;
            NewMainRow["isProduce"] = 0;
            NewMainRow["isCheck"] = 0;
            NewMainRow["isVerify"] = false;
            NewMainRow["isClosed"] = false;
            NewMainRow["status"] = "未批";
            tMain.Rows.Add(NewMainRow);

            tDetail.Clear();
            DataRow NewDetailRow = tDetail.NewRow();
            NewDetailRow["Discount"] = 1;
            NewDetailRow["OrderCode"] = tMain.Rows[0]["code"];
            tDetail.Rows.Add(NewDetailRow);

            SetControlsData();
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            SelectBillFrm frm = new SelectBillFrm();
            if (OrderType == GRWL.BZSC.Common.EnumCommon.OrderTypes.CG)
                frm.SetCondition(GRWL.BZSC.Common.EnumCommon.BillType.CG, BillPrefix, false);
            else
                frm.SetCondition(GRWL.BZSC.Common.EnumCommon.BillType.DH, BillPrefix, false);
            frm.ShowDialog();
            if (frm.SelectBills.Count > 0)
            {
                OpenBill(frm.SelectBills[0].BillId);
            }
        }

        /// <summary>
        /// 选择已保存单据，打开继续上一次编辑
        /// </summary>
        /// <param name="BillId"></param>
        private void OpenBill(int BillId)
        {
            xMain = BaseDataProxy.GetXOrder(BillId);
            xDetials = BaseDataProxy.GetXOrderDetails(BillId);
            if (xMain != null)
            {
                //表头内容
                IEnumerable<XOrder> ary = new List<XOrder>() { xMain };
                tMain = ary.ConvertToDataTable<TB_Order>();
                if (xDetials != null)
                {
                    //表体内容
                    tDetail = xDetials.ConvertToDataTable<TB_OrderDetail>();
                }

                //if (!string.IsNullOrEmpty(tMain.Rows[0]["assessor"].ToString()))
                if ((bool)tMain.Rows[0]["isVerify"] == true)
                {
                    //审批后,不允许再修改
                    EditStatus = Common.BillOperateType.View;
                    SetControlsStatus(false);
                }
                else
                {
                    //未审批,允许再修改
                    tMain.Rows[0]["mender"] = SysLoginUserInfo.UserId;
                    tMain.Rows[0]["MenderName"] = SysLoginUserInfo.UserName;
                    tMain.Rows[0]["updateTime"] = DateTime.Now;
                    EditStatus = Common.BillOperateType.Update;
                    SetControlsStatus(true);
                }

                SetControlsData();
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {

            if ((EditStatus != Common.BillOperateType.Add) & (EditStatus != Common.BillOperateType.Update) & (EditStatus != Common.BillOperateType.Delete))
                return;

            //保存修改
            if (!GetControlsData())
                return;
            if ((EditStatus == Common.BillOperateType.Add) && string.IsNullOrEmpty(tMain.Rows[0]["code"].ToString()))
            {
                tMain.Rows[0]["code"] = BaseDataProxy.GetSerialNo(1, BillPrefix, 4, true, true, true);
                edtBillCode.Text = tMain.Rows[0]["code"].ToString();
            }
            tMain.AcceptChanges();

            foreach (DataRow dr in tDetail.Rows)
            {
                if (string.IsNullOrEmpty(dr["OrderCode"].ToString()))
                    dr["OrderCode"] = tMain.Rows[0]["code"];
            }
            tDetail.AcceptChanges();

            //将 DataTable 转换为写入后台格式 TB_xxxxx
            tbOrder = OTConverter.ConvertToObject<TB_Order>(tMain.Rows[0]);
            List<TB_OrderDetail> lsOrderDetails = OTConverter.ConvertTableToObject<TB_OrderDetail>(tDetail);
            tbOrderDetails = lsOrderDetails.ToArray();

            //保存方法，支持主/细单一次写入到后台。
            tbOrder.TB_OrderDetail = tbOrderDetails;

            int iAddID = -1;
            bool bUpdate = false;

            if (EditStatus == Common.BillOperateType.Add)
            {
                iAddID = BaseDataProxy.AddOrder(tbOrder);
                tMain.Rows[0]["id"] = iAddID;
            }
            else // (EditStatus == Common.BillOperateType.Update)
            {
                bUpdate = BaseDataProxy.UpdateOrder(tbOrder, true);
            }

            if (((EditStatus == Common.BillOperateType.Add) && (iAddID > 0)) || ((EditStatus == Common.BillOperateType.Update) && (bUpdate)))
            {
                MessageBox.Show("已成功保存单据.");
                EditStatus = Common.BillOperateType.Update;
                OpenBill(Common.StringToInt(tMain.Rows[0]["id"].ToString()));
                //SetControlsStatus(false);
            }
            else
                MessageBox.Show("保存单据失败.");
        }

        /// <summary>
        /// 导入订单
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnImportOrds_Click(object sender, EventArgs e)
        {
            SelectBillFrm frm = new SelectBillFrm();
            //暂时只允许选择一张单返回
            frm.SetCondition(GRWL.BZSC.Common.EnumCommon.BillType.DH, "DH", false);
            frm.ShowDialog();
            if (frm.SelectBills.Count > 0)
            {
                ImportBill(frm.SelectBills[0].BillId, GRWL.BZSC.Common.EnumCommon.BillType.DH);
                //EditStatus = Common.BillOperateType.Update;
            }

        }

        /// <summary>
        /// 导入申购单
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnImportReqs_Click(object sender, EventArgs e)
        {
            SelectBillFrm frm = new SelectBillFrm();
            //暂时只允许选择一张单返回
            frm.SetCondition(GRWL.BZSC.Common.EnumCommon.BillType.QG, "QG", false);
            frm.ShowDialog();
            if (frm.SelectBills.Count > 0)
            {
                ImportBill(frm.SelectBills[0].BillId, GRWL.BZSC.Common.EnumCommon.BillType.QG);
                //EditStatus = Common.BillOperateType.Update;
            }

        }

        /// <summary>
        /// 从上一业务流程导入单据内容
        /// </summary>
        /// <param name="iBillId"></param>
        /// <param name="ImportBillType"></param>
        private void ImportBill(int iBillId, GRWL.BZSC.Common.EnumCommon.BillType ImportBillType)
        {
            //if (list.Count == 0)
            if (iBillId == 0)
                return;

            //表头内容 用户输入不需要处理
            //表体内容
            if ((theView.Rows.Count >= 1) || (theView.Rows[0].Cells["MaterialCode"].Value != null))
            {
                string message = "导入前是否删除已有记录？";
                string caption = "确认";
                MessageBoxButtons buttons = MessageBoxButtons.YesNo;
                DialogResult result = MessageBox.Show(message, caption, buttons);
                if (result == DialogResult.Yes)
                {
                    tDetail.Clear();
                }
            }

            if (ImportBillType == GRWL.BZSC.Common.EnumCommon.BillType.QG)
            {
                ImportRequisition(iBillId);
            }
            if (ImportBillType == GRWL.BZSC.Common.EnumCommon.BillType.DH)
            {
                ImportOrder(iBillId);
            }

            SetControlsData();
            SetControlsStatus(true);
        }

        /// <summary>
        /// 导入申购单内容
        /// </summary>
        /// <param name="iBillId"></param>
        private void ImportRequisition(int iBillId)
        {
            DataTable tbImport = new DataTable();
            TB_Requisition xImportReqs = BaseDataProxy.GetRequisition(iBillId);
            if (xImportReqs != null)
            {
                if (xImportReqs.trader != null)
                    tMain.Rows[0]["trader"] = xImportReqs.trader;
                tMain.Rows[0]["memo"] = xImportReqs.memo;

                TB_ReqDetail[] xImportReqDetails = BaseDataProxy.GetReqDetails(iBillId);
                if ((xImportReqDetails != null) && (xImportReqDetails.Count() > 0))
                {
                    if (xImportReqDetails[0].pDate!=null)
                    {
                        tMain.Rows[0]["deliveryDate"] = xImportReqDetails[0].pDate;
                    }
                    foreach (TB_ReqDetail tbItem in xImportReqDetails)
                    {
                        DataRow dr = tDetail.NewRow();
                        dr["PrevId"] = tbItem.reqn;
                        dr["PrevCode"] = tbItem.reqnCode;
                        dr["PrevType"] = "QG";
                        dr["material"] = tbItem.material;
                        dr["materialCode"] = tbItem.materialCode;
                        dr["Discount"] = 1;
                        if (tbItem.num != null)
                        {
                            dr["Num"] = tbItem.num;
                            dr["ReqNum"] = tbItem.num;
                        }
                        QMaterial[] QMaterialFind = BaseDataProxy.FindMaterials(false, null, null, null, tbItem.materialCode, null,null,null,null,null);
                        if ((QMaterialFind == null) || (QMaterialFind.Count() == 0))
                            continue;
                        //if (theView.CurrentRow.Cells["MaterialId"].ToString() == QMaterialFind[0].Id.ToString())
                        //    continue;
                        dr["MaterialName"] = QMaterialFind[0].CnName;
                        dr["Specs"] = QMaterialFind[0].Specs;
                        dr["Unit"] = QMaterialFind[0].Unit;                        
                        // 非标准规格字段
                        dr["specs"] = QMaterialFind[0].Specs;
                        tDetail.Rows.Add(dr);
                    }
                }
            }
        }

        /// <summary>
        /// 导入订货单内容
        /// </summary>
        /// <param name="iBillId"></param>
        private void ImportOrder(int iBillId)
        {
            DataTable tbImport = new DataTable();
            XOrder xImportOrder = BaseDataProxy.GetXOrder(iBillId);
            if (xImportOrder != null)
            {
                tMain.Rows[0]["trader"] = xImportOrder.Order.trader;
                tMain.Rows[0]["memo"] = xImportOrder.Order.memo;
                tMain.Rows[0]["deliveryDate"] = xImportOrder.Order.deliveryDate;
            }

            XOrderDetail[] xImportDetails = BaseDataProxy.GetXOrderDetails(iBillId);
            if ((xImportDetails != null) && (xImportDetails.Count() > 0))
            {
                foreach (XOrderDetail tbItem in xImportDetails)
                {
                    DataRow dr = tDetail.NewRow();
                    dr["PrevId"] = xImportOrder.Order.id;
                    dr["PrevCode"] = xImportOrder.Order.code;
                    dr["PrevType"] = "DH";
                    dr["material"] = tbItem.OrderDetail.material;
                    dr["MaterialCode"] = tbItem.OrderDetail.materialCode;
                    dr["MaterialName"] = tbItem.MaterialName;
                    dr["Specs"] = tbItem.Specs;
                    dr["Unit"] = tbItem.Unit;
                    dr["Discount"] = 1;
                    if (tbItem.OrderDetail.num != null)
                    {
                        dr["Num"] = tbItem.OrderDetail.num;
                        dr["ReqNum"] = tbItem.OrderDetail.num;
                    }
                    // 非标准规格字段
                    dr["specs"] = tbItem.Specs;
                    tDetail.Rows.Add(dr);
                }
            }
        }

        private void btnSelect_Click(object sender, EventArgs e)
        {
            btnSelect.ShowDropDown();
        }

        private void btnAddItem_Click(object sender, EventArgs e)
        {
            //新行默认值设定
            DataRow dr = tDetail.NewRow();
            dr["Discount"] = 1;
            dr["OrderCode"] = tMain.Rows[0]["code"];
            tDetail.Rows.Add(dr);
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            //if (!string.IsNullOrEmpty(tMain.Rows[0]["assessor"].ToString()))
            if ((bool)tMain.Rows[0]["isVerify"] == true)
            {
                MessageBox.Show("无法删除已审批单据.");
                return;
            }

            //if (EditStatus == Common.BillOperateType.Add)
            //{
            //    tMain.Rows.Clear();
            //    tDetail.Rows.Clear();
            //    return;
            //}

            if ((EditStatus != Common.BillOperateType.Add) & (EditStatus != Common.BillOperateType.Update))
                return;

            if (EditStatus == Common.BillOperateType.Update)
            {
                if (tMain.Rows[0]["id"] == DBNull.Value)
                    return;

                int BillId = Common.StringToInt(tMain.Rows[0]["id"].ToString());
                string message = "是否删除单据？";
                string caption = "确认";
                MessageBoxButtons buttons = MessageBoxButtons.YesNo;
                DialogResult result = MessageBox.Show(message, caption, buttons);
                if (result != DialogResult.Yes)
                    return;

                bool bDelOk = BaseDataProxy.DeleteOrder(BillId);
                if (bDelOk)
                {
                    MessageBox.Show("已成功删除单据.");
                    EditStatus = Common.BillOperateType.View;
                }
                else
                {
                    MessageBox.Show("无法删除单据.");
                    return;
                }

            }

            // 初始化所有记录
            tMain.Rows.Clear();
            tDetail.Rows.Clear();
            tMain.Rows.Add();
            //tDetail.Rows.Add();

            SetControlsData();
            SetControlsStatus(false);

            EditStatus = Common.BillOperateType.None;
            return;
        }

        private void btnDelItem_Click(object sender, EventArgs e)
        {
            if (theView.RowCount > 0)
            {
                theView.Rows.RemoveAt(theView.CurrentRow.Index);
                tDetail.AcceptChanges();
                // 删除所有记录后，自动建立一个空白记录
                if (theView.RowCount == 0)
                {
                    btnAddItem_Click(null, null);
                    tDetail.AcceptChanges();
                }
            }

        }

        private void btnMaterial_Click(object sender, EventArgs e)
        {
            FindMaterialFrm frm = new FindMaterialFrm();
            frm.StockNullable = true;
            frm.Text = "选择物资";
            if (frm.ShowDialog() == DialogResult.OK)
            {
                theView.CurrentRow.Cells["MaterialId"].Value = frm.SelectorItem.Id;
                theView.CurrentRow.Cells["MaterialCode"].Value = frm.SelectorItem.Code;
                theView.CurrentRow.Cells["MaterialName"].Value = frm.SelectorItem.CnName;
                theView.CurrentRow.Cells["Specs"].Value = frm.SelectorItem.Specs;
                theView.CurrentRow.Cells["Unit"].Value = frm.SelectorItem.Unit;
                // 非标准规格字段
                theView.CurrentRow.Cells["specs"].Value = frm.SelectorItem.Specs;
            }

        }

        private void btnPrint_Click(object sender, EventArgs e)
        {

        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            EditStatus = Common.BillOperateType.None;

            Close();
        }
        #endregion

        #region 主单部分
        private void traderSelector_SelectorClick(object sender, EventArgs e)
        {
            if ((EditStatus != Common.BillOperateType.Add) & (EditStatus != Common.BillOperateType.Update))
            {
                return;
            }

            TraderFrm frm = new TraderFrm();
            if (OrderType == GRWL.BZSC.Common.EnumCommon.OrderTypes.CG)
            {
                frm.Text = "选择供应商";
                frm.SearchSupplierMode(); // .SetTraderAsSupplier();
            }
            else
            {
                frm.Text = "选择客户";
                frm.SearchClientMode(); //.SetTraderAsClient();
            }

            if (frm.ShowDialog() == DialogResult.OK)
            {
                edtTrader.SetSelected(frm.SelectorItem);
                tMain.Rows[0]["trader"] = Common.StringToInt(frm.SelectorItem.Value);
            }
        }

        private void UpdateBizManList(int DepartmentId)
        {
            XUsers = BaseDataProxy.FindUsers(DepartmentId, "", "");

            //XUsers.copy order by user name
            //刷新部门对应业务员，按名字排序显示
            IEnumerable<XUser> query = XUsers.OrderBy(XUser => XUser.User.name);
            edtBizMan.Items.Clear();
            if (query.Count() == 0)
                return;
            foreach (XUser rc in query)
            {
                edtBizMan.Items.Add(rc.User);
            }
            edtBizMan.DisplayMember = "name";
            edtBizMan.ValueMember = "id";
        }

        private void departmentUTextBox_SelectorClick(object sender, EventArgs e)
        {
            if ((EditStatus != Common.BillOperateType.Add) & (EditStatus != Common.BillOperateType.Update))
            {
                return;
            }

            DeptFrm frm = new DeptFrm();
            if (frm.ShowDialog() == DialogResult.OK)
            {
                edtDepartment.SetSelected(frm.SelectorItem);
                tMain.Rows[0]["department"] = Common.StringToInt(frm.SelectorItem.Key);
                UpdateBizManList(Common.StringToInt(frm.SelectorItem.Key));
            }
        }

        private void businessmanUTextBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            //string sBizManName = edtBizMan.Text;
            //IEnumerable<XUser> rDp = from dp in XUsers
            //                         where dp.User.name == sBizManName
            //                         select dp;

            //tMain.Rows[0]["businessman"] = rDp.First().User.id;
        }

        private void cmbTaxRate_SelectedIndexChanged(object sender, EventArgs e)
        {
            if ((EditStatus != Common.BillOperateType.Add) & (EditStatus != Common.BillOperateType.Update))
                return;

            decimal dTaxRate;
            if (cmbTaxRate.SelectedIndex == 0)
                dTaxRate = 0;
            else
                dTaxRate = Common.StringToDecimal(cmbTaxRate.Text);

            foreach (DataGridViewRow dgvr in theView.Rows)
            {
                if (dTaxRate != 0)
                    dgvr.Cells["TaxRate"].Value = dTaxRate;
                else
                    dgvr.Cells["TaxRate"].Value = DBNull.Value;
                ReCalcRowMoney(dgvr);
            }
        }

        private void cmbTaxRate_Validated(object sender, EventArgs e)
        {
            if ((EditStatus != Common.BillOperateType.Add) & (EditStatus != Common.BillOperateType.Update))
                return;

            decimal dTaxRate = Common.StringToDecimal(cmbTaxRate.Text);

            if (dTaxRate > 0)
                if (cmbTaxRate.Items.IndexOf(cmbTaxRate.Text) < 0)
                {
                    cmbTaxRate.Items.Add(cmbTaxRate.Text);

                    foreach (DataGridViewRow dgvr in theView.Rows)
                    {
                        dgvr.Cells["TaxRate"].Value = dTaxRate;
                        ReCalcRowMoney(dgvr);
                    }
                }

        }
        #endregion

        private void btnConfirm_ButtonClick(object sender, EventArgs e)
        {
            btnConfirm.ShowDropDown();

        }

        private void UpdateStatus(int BillId)
        {
            XOrder xMain = BaseDataProxy.GetXOrder(BillId);
            if (xMain == null)
                return;

            if (xMain.Order.assessor == null)
                tMain.Rows[0]["assessor"] = DBNull.Value;
            else
                tMain.Rows[0]["assessor"] = xMain.Order.assessor;
            if (xMain.Order.verifyTime == null)
                tMain.Rows[0]["verifyTime"] = DBNull.Value;
            else
                tMain.Rows[0]["verifyTime"] = xMain.Order.verifyTime.Value.ToLongTimeString();
            tMain.Rows[0]["status"] = xMain.Order.status;
            tMain.Rows[0]["AssessorName"] = xMain.AssessorName;
            tMain.AcceptChanges();

            edtAssessor.Text = xMain.AssessorName;
            edtVerifyTime.Text = xMain.Order.verifyTime.ToString();
            edtBillStatus.Text = xMain.Order.status;

        }

        private void btnConfirmOk_Click(object sender, EventArgs e)
        {
            try
            {
                int BillId = Common.StringToInt(tMain.Rows[0]["id"].ToString());
                VerifyBillResult vbResult = BaseDataProxy.VerifyBill(BillPrefix, BillId, SysLoginUserInfo.UserId, true);
                MessageBox.Show(vbResult.Message);
                if (vbResult.Pass)
                {
                    //UpdateStatus(BillId);
                    //EditStatus = Common.BillOperateType.View;
                    //SetControlsStatus(false);
                    //theView.Refresh();
                    OpenBill(Common.StringToInt(tMain.Rows[0]["id"].ToString()));
                }
            }
            catch
            {
            }
        }

        private void btnConfirmCancel_Click(object sender, EventArgs e)
        {
            try
            {
                int BillId = Common.StringToInt(tMain.Rows[0]["id"].ToString());
                VerifyBillResult vbResult = BaseDataProxy.VerifyBill(BillPrefix, BillId, SysLoginUserInfo.UserId, false);
                MessageBox.Show(vbResult.Message);
                if (vbResult.Pass)
                {
                    //UpdateStatus(BillId);
                    //EditStatus = Common.BillOperateType.Update;
                    //SetControlsStatus(true);
                    //theView.Refresh();
                    OpenBill(Common.StringToInt(tMain.Rows[0]["id"].ToString()));
                }
            }
            catch
            {
            }
        }

        private void edtTrader_SelectorTextUpdate(object sender, EventArgs e)
        {
            TB_Trader[] datas = BaseDataProxy.FindTraders(null, true, null, null, null, (sender as Selector).GetComboBoxText());
            (sender as Selector).ReBindComboBox<TB_Trader>(datas, "id", "name", "code");

        }


    }
}
